<template>
  <div class="chat-div">
    <div v-show="showChatBox" class="chat-main">
      <div id="messagediv" class="messagediv">
        <!-- 聊天记录 -->
        <div class="item">
          <img class="avatar" :src="aiAvatar" />
          <div class="answerDiv">
            <p>我是AI智能小助手，有问题请咨询我吧！</p>
          </div>
        </div>
        <div v-for="(item, index) in messageList" :key="index" class="item">
          <img v-if="item.role == 'assistant'" class="avatar" :src="aiAvatar" />
          <img v-if="item.role == 'user'" class="avatar" :src="userAvatar" />
          <div class="answerDiv">
            <p
              v-if="!item.loading && item.type !== 'image'"
              v-html="item.content"
            ></p>
            <p v-if="item.loading">思考中 <i class="el-icon-loading"></i></p>
            <a
              v-if="
                index == messageList.length - 1 &&
                item.role == 'assistant' &&
                (loading || speaking)
              "
              href="#"
              @click="stopAnswer"
              >停止回答</a
            >
            <img
              v-if="item.type === 'image'"
              :src="item.imageSrc"
              alt="图片"
              style="max-width: 100%; max-height: 200px"
            />
          </div>
        </div>
      </div>
      <div class="sendDiv">
        <el-input
          @keyup.enter.native="getAnswer"
          v-model="question"
          placeholder="输入问题搜一搜"
        ></el-input>
        <el-button @click="getAnswer">
          <i class="el-icon-s-promotion"></i>
        </el-button>
        <input
          type="file"
          @change="onFileSelected"
          accept="image/*"
          style="display: none"
          ref="fileInput"
        />
        <el-button @click="$refs.fileInput.click()">
          <i class="el-icon-upload2"></i>
        </el-button>
        <el-button @click="uploadImageWithPrompt" v-if="selectedFile">
          <i class="el-icon-upload"></i> 上传图片
        </el-button>
      </div>
    </div>
    <div v-show="showChatBox" class="close-btn" @click="showChatBox = false">
      <i class="el-icon-close"></i>
    </div>
    <div v-show="!showChatBox" class="small-window" @click="showChatBox = true">
      AI问答
    </div>
  </div>
</template>

<script>
import { sendMsg, uploadImage } from "@/api/aichat";
import { sign } from "@/utils/securityUtil";
import aiAvatar from "@/assets/images/ai-avatar.jpg";
import userAvatar from "@/assets/images/user-avatar.jpg";
import { marked } from "marked";
export default {
  name: "QianFanChat",
  data() {
    return {
      showChatBox: false,
      loading: false,
      speaking: false,
      aiAvatar,
      userAvatar,
      question: "",
      messageList: [], // 初始化消息列表
      selectedFile: null, // 存储选中的文件
      // 逐字输出 START
      timer: null,
      length: 0,
      index: 0,
      // 逐字输出 END
    };
  },
  methods: {
    getAnswer() {
      if (this.loading) {
        this.$message({ type: "warning", message: "正在回答，请耐心等待！" });
        return;
      }
      if (!this.question.trim()) {
        this.$message({ type: "warning", message: "请输入内容！" });
        return;
      }
      this.loading = true;
      let tmpQuestion = this.question;
      this.question = "";

      // 添加用户消息
      this.messageList.push({
        role: "user",
        content: tmpQuestion,
        loading: false,
      });

      // 添加助手消息
      this.messageList.push({ role: "assistant", content: "", loading: true });

      this.$nextTick(() => {
        this.scroll();
      });

      let params = {
        messages: JSON.stringify(this.messageList),
      };

      params.timestamp = new Date().getTime();
      params.signature = sign(params);
      sendMsg(params)
        .then((res) => {
          if (!this.loading) {
            return;
          }
          this.messageList[this.messageList.length - 1].loading = false;

          this.index = 0;
          this.length = res.length;
          this.handleSpeak(res);
          this.timer = setInterval(() => {
            if (this.index <= this.length - 1) {
              let word = res.charAt(this.index);
              if (word == "\n") {
                word = "<br>";
              }
              this.messageList[this.messageList.length - 1].content += word;
              this.index++;
            } else {
              this.loading = false;
              clearInterval(this.timer);
            }
            this.scroll();
          }, 30);
        })
        .catch((error) => {
          this.loading = false;
          this.messageList[this.messageList.length - 1].loading = false;
          this.messageList[this.messageList.length - 1].content =
            "对话失败，请重试！";
          this.scroll();
        });
    },
    onFileSelected(event) {
      this.selectedFile = event.target.files[0];
    },
    uploadImageWithPrompt() {
      if (!this.question.trim()) {
        this.$message({ type: "warning", message: "请输入问题后再上传图片！" });
        return;
      }

      const file = this.selectedFile;
      if (!file) return;

      const formData = new FormData();
      formData.append("image", file);

      const params = {
        timestamp: new Date().getTime(),
        signature: sign({ timestamp: new Date().getTime() }),
        prompt: this.question.trim(), // 添加 prompt 参数
      };

      formData.append(
        "params",
        new Blob([JSON.stringify(params)], { type: "application/json" })
      );

      this.loading = true;
      this.messageList.push({
        role: "user",
        content: this.question.trim(),
        type: "image",
        imageSrc: URL.createObjectURL(file),
        loading: false,
      });

      // 添加助手消息
      this.messageList.push({ role: "assistant", content: "", loading: true });

      this.$nextTick(() => {
        this.scroll();
      });

      uploadImage(formData)
        .then((response) => {
          if (!this.loading) {
            return;
          }
          this.handleSpeak(response);
          this.messageList[this.messageList.length - 1].loading = false;

          // 检查返回的内容
          console.log("Response from backend:", response);

          // 使用 marked 解析 Markdown 内容
          this.messageList[this.messageList.length - 1].content =
            marked(response);

          console.log(
            "Parsed HTML:",
            this.messageList[this.messageList.length - 1].content
          );

          this.loading = false;
          this.scroll();
        })
        .catch((error) => {
          this.loading = false;
          this.messageList[this.messageList.length - 1].loading = false;
          this.messageList[this.messageList.length - 1].content =
            "图片识别失败，请重试！";
          this.scroll();
        });
    },
    scroll() {
      const messagediv = document.getElementById("messagediv");
      messagediv.scrollTo({
        top: messagediv.scrollHeight,
      });
    },
    stopAnswer() {
      this.handleStop();
      clearInterval(this.timer);
      this.length = 0;
      this.index = 0;
      this.loading = false;

      let lastMsg = this.messageList[this.messageList.length - 1];
      if (!lastMsg.content) {
        lastMsg.loading = false;
        lastMsg.content = "请继续向我提问吧！";
      }
    },
    handleSpeak(text) {
      this.handleStop();
      this.speaking = true;
      const msg = new SpeechSynthesisUtterance();
      msg.text = text;
      msg.lang = "zh-CN";
      msg.volume = 0.5;
      msg.rate = 1.6;
      msg.pitch = 1.5;
      msg.onend = () => {
        this.speaking = false;
      };
      speechSynthesis.speak(msg);
    },
    handleStop() {
      this.speaking = false;
      speechSynthesis.cancel();
    },
  },
};
</script>

<style lang="scss" scoped>
::v-deep {
  .el-input {
    width: 270px;
    input {
      background-color: rgba(0, 0, 0, 0.5);
      border: none;
      color: white;
    }
  }
  .el-button {
    background-color: rgba(0, 0, 0, 0.5);
    border: none;
    margin-left: 10px;
    padding: 0 20px;
    i {
      font-size: 20px;
      color: white;
    }
    &:focus {
      background-color: rgba(0, 0, 0, 0.5);
    }
    &:hover {
      background-color: white;
      i {
        color: black;
      }
    }
  }
}
.chat-div {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  z-index: 99;
  cursor: pointer;
  .close-btn {
    margin-top: 18px;
    color: white;
    background-color: rgba(0, 0, 0, 0.6);
    height: 30px;
    width: 30px;
    text-align: center;
    line-height: 30px;
    border-radius: 50%;
  }
  .small-window {
    color: white;
    margin-top: 18px;
    padding: 10px;
    background-color: rgba(16, 168, 129, 0.8);
    width: 26px;
    font-size: 20px;
    border-top-right-radius: 10px;
    border-bottom-right-radius: 10px;
  }
}
.chat-main {
  border-radius: 4px;
  margin: 10px 0;
  padding: 0.1rem 0.1rem;
  width: 374px;
  .messagediv {
    overflow: auto;
    max-height: 60vh;
    .item {
      display: flex;
      margin-bottom: 0.1rem;
      .avatar {
        width: 40px;
        height: 40px;
      }
      .answerDiv {
        p {
          color: white;
          background-color: rgba(0, 0, 0, 0.6);
          padding: 10px;
          margin: 0 10px;
          font-size: 16px;
          border-radius: 6px;
          text-align: left;
        }
        a {
          cursor: pointer;
          font-size: 15px;
          color: red;
          text-decoration: underline;
          margin-left: 10px;
          font-weight: bold;
        }
        img {
          max-width: 100%;
          max-height: 200px;
        }
      }
    }
    &::-webkit-scrollbar {
      width: 0;
    }
  }
  .sendDiv {
    display: flex;
    justify-content: end;
    margin: 10px 10px 0 0;
  }
}
</style>